package edu.tjut.tjutcommunity.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.tjut.tjutcommunity.TjutCommunityApplication;
import edu.tjut.tjutcommunity.entity.SchoolCookie;
import edu.tjut.tjutcommunity.entity.User;
import edu.tjut.tjutcommunity.entity.UserCookie;
import edu.tjut.tjutcommunity.handler.LoginHandler;
import edu.tjut.tjutcommunity.httpInterface.LoginHttp;
import edu.tjut.tjutcommunity.httpInterface.XXMHHttp;
import edu.tjut.tjutcommunity.mapper.UserMapper;
import edu.tjut.tjutcommunity.service.AcademyService;
import edu.tjut.tjutcommunity.service.UserService;
import edu.tjut.tjutcommunity.utils.CookieUtils;
import edu.tjut.tjutcommunity.utils.UserUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yhh
 * @since 2022-04-14
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final static Logger logger = LoggerFactory.getLogger(TjutCommunityApplication.class);

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    final
    AcademyService academyService;
    final XXMHHttp xxmhHttp;
    final
    LoginHttp loginHttp;
    final
    LoginHandler loginHandler;

    final
    UserMapper userMapper;

    public UserServiceImpl(LoginHandler loginHandler, UserMapper userMapper, AcademyService academyService, XXMHHttp xxmhHttp, LoginHttp loginHttp) {
        this.loginHandler = loginHandler;
        this.userMapper = userMapper;
        this.academyService = academyService;
        this.xxmhHttp = xxmhHttp;
        this.loginHttp = loginHttp;
    }

    /**
     * 登录接口
     *
     * @param stuId
     * @param password
     * @return
     * @throws Exception
     */
    @Override
    public User login(String stuId, String password) throws Exception {
        //访问学校的接口，获取到学校通行证
        String cookieJson = stringRedisTemplate.opsForValue().get(stuId + "_cookie");
        UserCookie cookie;

        if (cookieJson == null) {
            cookie = new UserCookie();
        } else {
            cookie = JSON.parseObject(cookieJson, UserCookie.class);
        }
        //访问学校的登录接口，出现异常既登录失败
        loginHandler.login(stuId, password, cookie);

        if (cookie != null) {
            //将cookie加入到redis中,60分钟过期
            stringRedisTemplate.opsForValue().set(stuId + "_cookie", JSON.toJSONString(cookie), 60, TimeUnit.MINUTES);
        }
        //访问数据库，如果有记录，返回该记录，如果没有记录，访问学校的userinfo接口。
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("student_id", stuId);
        User user = userMapper.selectOne(qw);
        if (user == null) {
            user = new User();
            //访问学校的用户接口,相当于注册用户
            String userDepartment = loginHandler.getUserDepartment(cookie, stuId);
            //获取学院序号
            Integer academyId = academyService.getNo(userDepartment);
            user.setAcademyId(academyId);
            user.setAcademyName(userDepartment);
            //设置随机昵称(未处理
            int insert = insertUser(stuId, user);
            if (insert == 0) return null;
        }
        //获取刚插入用户的uid
        Integer uid = getUidByStuId(stuId);
        user.setUid(uid);
        //将user信息一并存入redis,同60分钟过期                 这行是拿来干嘛的来着？。。。
        stringRedisTemplate.opsForValue().set(stuId + "_userInfo", JSON.toJSONString(user), 60, TimeUnit.MINUTES);
        return user;
    }

    private int insertUser(String stuId, User user) {
        String name = "社区用户" + UserUtil.getRandomString(10);
        while (!checkUsername(name)) {
            name = "社区用户" + UserUtil.getRandomString(10);
        }
        user.setUsername(name);
        user.setStudentId(stuId);
        user.setPrefList("{\"0\":{},\"1\":{},\"2\":{}}");
        user.setLastOnlineTime(new Date());
        int insert = userMapper.insert(user);
        return insert;
    }

    /**
     * 更新用户昵称
     *
     * @param stuId
     * @param name
     * @return
     */
    @Override
    public boolean updateUsernameById(String stuId, String name) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("student_id", stuId);
        User user = userMapper.selectOne(qw);
        if (user == null) return false;
        user.setUsername(name);
        int i = userMapper.updateById(user);
        if (i == 1) {
            //清除redis
            stringRedisTemplate.delete(stuId + "_userInfo");
        }
        return true;
    }

    /**
     * 通过学号获取用户
     *
     * @param stuId
     * @return
     */
    @Override
    public User getUserByStuId(String stuId) {
        if (stuId == null) return null;
        //尝试从redis获取用户信息
        String userInfoJson = stringRedisTemplate.opsForValue().get(stuId + "_userInfo");
        User user = JSON.parseObject(userInfoJson, User.class);
        if (user != null) return user;
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("student_id", stuId);
        user = userMapper.selectOne(qw);
        stringRedisTemplate.opsForValue().set(stuId + "_userInfo", JSON.toJSONString(user), 600, TimeUnit.SECONDS);
        return user;
    }

    /**
     * 通过学号获取uid 索引覆盖
     *
     * @param stuId
     * @return
     */
    @Override
    public Integer getUidByStuId(String stuId) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("student_id", stuId);
        qw.select("uid");
        User user = userMapper.selectOne(qw);
        return user.getUid();
    }

    /**
     * 通过学号获取uid和用户名
     *
     * @param stuId
     * @return
     */
    @Override
    public User getUidAndUsernameByStuId(String stuId) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("student_id", stuId);
        qw.select("uid", "username");
        User user = userMapper.selectOne(qw);
        return user;
    }

    /**
     * 更新用户在线时间
     *
     * @param stuId
     */
    @Override
    public Boolean updateOnlineTime(String stuId) {
        Integer uid = getUidByStuId(stuId);
        User user = new User();
        user.setUid(uid);
        user.setLastOnlineTime(new Date());
        return userMapper.updateById(user) == 1;
    }

    /**
     * 检查用户名是否重复
     *
     * @param username
     * @return
     */
    @Override
    public boolean checkUsername(String username) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("username", username);
        User user = userMapper.selectOne(qw);
        return user == null;
    }

    /**
     * 通过uid获取学号
     *
     * @param uid
     * @return
     */
    @Override
    public User getStuIdById(Integer uid) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.select("student_id");
        qw.eq("uid", uid);
        return userMapper.selectOne(qw);
    }

    @Override
    public Boolean updateUserById(User user) {
        return userMapper.updateById(user) == 1;
    }

    @Override
    public List<User> getUsers() {
        return userMapper.selectList(null);
    }

    @Override
    public List<User> getUsers(String activeDay) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.gt("last_online_time", activeDay);
        return userMapper.selectList(qw);
    }

    @Override
    public User checkCookieFromXXMH(SchoolCookie cookie) {
        if (cookie.getAsessionid() == null || cookie.getIPlanetDirectoryPro() == null)
            return null;
        //根据学号id检查是否存在该用户，如果不存在，注册，如果存在，直接返回用户数据
        //发起网络请求
        String cookieFromCookieClass = CookieUtils.getCookieFromCookieClass(cookie);
        //应该是请求redis，避免多次请求信息门户
        String userInfoFromXXMH = xxmhHttp.getUserInfoFromXXMH(cookieFromCookieClass);
        JSONObject jsonObject = JSONObject.parseObject(userInfoFromXXMH);
        String userName = jsonObject.getString("userName");//真实名称
        String userId = jsonObject.getString("userId");//学号
        Integer schoolID = jsonObject.getInteger("schoolID");//学院代码
        String userDepartment = jsonObject.getString("userDepartment");//学院名称

//        user.setUsername(userName);获取的是用户的真实名称

        //查询数据库
        User userIndb = getUserByStuId(userId);

        if (userIndb == null) {
            //注册
            userIndb = new User();
            userIndb.setAcademyName(userDepartment);
            userIndb.setAcademyId(schoolID);
            userIndb.setStudentId(userId);
            insertUser(userId, userIndb);
            return userIndb;
        }
        //没有做任何缓存处理
        return userIndb;
    }

    @Override
    public List<User> getUsers(Collection<Integer> userIdsCol) {
        return userMapper.selectBatchIds(userIdsCol);
    }

    @Override
    public User updateUserByStuId(User user) {
//        userMapper.updateById()
        return null;
    }
}
